home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Sprite 1984 - 1993
/
Sprite 1984 - 1993.iso
/
src
/
machserver
/
1.098
/
sync
/
syncSleep.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-03-20
|
6KB
|
252 lines
/*
* syncSleep.c --
*
* Interface between the timer module and processes that wish to sleep
* for a specified period of time.
*
* Copyright (C) 1985 Regents of the University of California
* All rights reserved.
*/
#ifndef lint
static char rcsid[] = "$Header: /sprite/src/kernel/sync/RCS/syncSleep.c,v 9.4 91/03/20 11:31:06 kupfer Exp $ SPRITE (Berkeley)";
#endif /* not lint */
#include <sprite.h>
#include <sync.h>
#include <syncInt.h>
#include <proc.h>
#include <sched.h>
#include <sig.h>
#include <stdlib.h>
#include <timer.h>
static Boolean WaitTimeSubr _ARGS_((Timer_Ticks wakeupTime));
/*
*----------------------------------------------------------------------
*
* Sync_WaitTime --
*
* Sleep for the specified period of time.
*
* Results:
* TRUE if aborted because of a signal, FALSE otherwise.
*
* Side effects:
* Process is put to sleep.
*
*----------------------------------------------------------------------
*/
Boolean
Sync_WaitTime(time)
Time time; /* Amount of time the process will sleep */
{
Timer_Ticks ticks;
Timer_Ticks wakeupTime;
Timer_Ticks currentTime;
/*
* Convert the passed-in time to ticks format.
*/
Timer_TimeToTicks(time, &ticks);
Timer_GetCurrentTicks(¤tTime);
Timer_AddTicks(currentTime, ticks, &wakeupTime);
return(WaitTimeSubr(wakeupTime));
}
/*
*----------------------------------------------------------------------
*
* Sync_WaitTimeInTicks --
*
* Sleep for the specified period of time.
*
* Results:
* TRUE if aborted because of a signal, FALSE otherwise.
*
* Side effects:
* Process is put to sleep.
*
*----------------------------------------------------------------------
*/
Boolean
Sync_WaitTimeInTicks(time)
Timer_Ticks time; /* Amount of time the process will sleep */
{
Timer_Ticks currentTime;
Timer_Ticks wakeupTime;
Timer_GetCurrentTicks(¤tTime);
Timer_AddTicks(currentTime, time, &wakeupTime);
return(WaitTimeSubr(wakeupTime));
}
/*
*----------------------------------------------------------------------
*
* Sync_WaitTimeInterval --
*
* Sleep for the specified period of time.
*
* Results:
* TRUE if aborted because of a signal, FALSE otherwise.
*
* Side effects:
* Process is put to sleep.
*
*----------------------------------------------------------------------
*/
Boolean
Sync_WaitTimeInterval(interval)
unsigned int interval; /* Amount of time the process will sleep */
{
Timer_Ticks wakeupTime;
Timer_Ticks currentTime;
/*
* Convert the passed-in time to ticks format.
*/
Timer_GetCurrentTicks(¤tTime);
Timer_AddIntervalToTicks(currentTime, interval, &wakeupTime);
return(WaitTimeSubr(wakeupTime));
}
/*
*----------------------------------------------------------------------
*
* WaitTimeSubr --
*
* Sleep until the specified time. This is done by
* atomically scheduling a call to Sync_WakeupProcess and causing
* the current process to wait on an event corresponding to its
* process control block pointer.
*
* Results:
* TRUE if aborted because of a signal, FALSE otherwise.
*
* Side effects:
* Process is put to sleep.
*
*----------------------------------------------------------------------
*/
static Boolean
WaitTimeSubr(wakeupTime)
Timer_Ticks wakeupTime; /* Time when process will wakeup */
{
Proc_ControlBlock *procPtr;
Timer_QueueElement wakeupElement;
Boolean wokeUp = FALSE;
Timer_Ticks currentTime;
Boolean sigPending;
int pnum;
procPtr = Proc_GetCurrentProc();
pnum = Mach_GetProcessorNumber();
wakeupElement.routine = Sync_WakeupProcess;
wakeupElement.clientData = (ClientData) procPtr;
wakeupElement.time = wakeupTime;
/*
* Get the scheduler master lock here. This is done to ensure that
* the wakeup call cannot precede the process's going to sleep.
* SyncEventWaitInt expects the sched_MutexPtr lock to be held upon entry.
*/
MASTER_LOCK(sched_MutexPtr);
Timer_ScheduleRoutine(&wakeupElement, FALSE);
/*
* Sleep until the designated time passes. This is done in a loop,
* since a process may be awakened by a spurious broadcast.
*/
do {
if (wokeUp) {
sync_Instrument[pnum].numSpuriousWakeups++;
#ifdef DEBUG
printf("Sync_WaitTime: woke up for wrong reason.\n");
#endif /* DEBUG */
}
sigPending = SyncEventWaitInt((unsigned int) procPtr, TRUE);
wokeUp = TRUE;
Timer_GetCurrentTicks(¤tTime);
} while (Timer_TickLT(currentTime, wakeupTime) && !sigPending);
(void) Timer_DescheduleRoutine(&wakeupElement);
#ifdef spur
Mach_InstCountEnd(1);
#endif
MASTER_UNLOCK(sched_MutexPtr);
return(sigPending);
}
/* STUB procedure */
ENTRY ReturnStatus
Sync_Sleep(time)
Time time; /* time process will sleep */
{
Timer_Ticks ticks;
/*
* Convert the passed-in time to ticks format.
*/
Timer_TimeToTicks(time, &ticks);
if (Sync_WaitTimeInTicks(ticks)) {
return(GEN_ABORTED_BY_SIGNAL);
} else {
return(SUCCESS);
}
}
/*
*----------------------------------------------------------------------
*
* Sync_WakeupProcess --
*
* Perform a broadcast to wake up a process after a timer event
* has gone off.
*
* This routine is equivalent to Sync_SlowBroadcast without the wait flag
* and with interrupts disabled.
*
* Results:
* None.
*
* Side effects:
* Make the process that was waiting for the timer event runnable.
*
*----------------------------------------------------------------------
*/
/* ARGSUSED */
void
Sync_WakeupProcess(time, procAddress)
Timer_Ticks time; /* passed by Timer module but ignored */
ClientData procAddress; /* address of PCB of process to wake up */
{
MASTER_LOCK(sched_MutexPtr);
SyncEventWakeupInt((unsigned int) procAddress);
MASTER_UNLOCK(sched_MutexPtr);
}